iT邦幫忙

2023 iThome 鐵人賽

DAY 1
0
自我挑戰組

掘地土撥鼠的設計歷險記系列 第 5

Builder Pattern - 生成器模式 實際應用

  • 分享至 

  • xImage
  •  

Hi all, 在上一篇我們寫了Builder Pattern的雛形,在這一篇我會接續這個模型來套在我們日常開發的案例中。

Introduction

這次案例中,將會以筆電生產來做例子🌰。
案例背景:目前有間筆電代工廠,然後他主要生產 Asus筆電及RoG系列筆電。

案例關聯

  • 使用端會新建一 Director 物件
  • Director內包含了Builder的 property,並使用它進行產品的生產
  • Builder為一個介面,主要會由 ROG 與 Asus這兩家的builder進行繼承及實作

UML

https://ithelp.ithome.com.tw/upload/images/20230904/20115082jHQ5zOJqRY.jpg

實戰

Product

package Products

type Labtop struct {
	LabtopType string
}

Builder

package Builders

import "builder/Products"

type Builder interface {
	SetLabtopType()
	GetLabtop() *Products.Labtop
}

RogBuilder

package Builders

import "builder/Products"

type RogBuilder struct {
	LabtopType string
}

func (rog *RogBuilder) SetLabtopType() {
	rog.LabtopType = "ROG"
}

func (rog *RogBuilder) GetLabtop() *Products.Labtop {
	rog.SetLabtopType()
	return &Products.Labtop{LabtopType: rog.LabtopType}
}

func NewRogBuilder() *RogBuilder {
	return &RogBuilder{}
}

AsusBuilder

package Builders

import "builder/Products"

type AsusBuilder struct {
	LabtopType string
}

func (a *AsusBuilder) SetLabtopType() {
	a.LabtopType = "ASUS"
}

func (a *AsusBuilder) GetLabtop() *Products.Labtop {
	a.SetLabtopType()
	return &Products.Labtop{LabtopType: a.LabtopType}
}

func NewAsusBuilder() *AsusBuilder {
	return &AsusBuilder{}
}

Director

package Directors

import (
	"builder/Builders"
	"builder/Products"
)

type Director struct {
	buider Builders.Builder
}

func (d *Director) SetBuilder(buider Builders.Builder) {
	d.buider = buider
}

func NewDirector() *Director {
	return &Director{}
}

func (d *Director) BuilderLabtop() *Products.Labtop {
	return d.buider.GetLabtop()
}

main

package main

import (
	"builder/Builders"
	"builder/Directors"
	"fmt"
)

func main() {

	asusBuilder := Builders.NewAsusBuilder()
	rogBuilder := Builders.NewRogBuilder()

	director := Directors.NewDirector()

	director.SetBuilder(asusBuilder)
	asus := director.BuilderLabtop()
	fmt.Println("AsusBuilder: " + asus.LabtopType)

	director.SetBuilder(rogBuilder)
	rog := director.BuilderLabtop()
	fmt.Println("RogBuilder: " + rog.LabtopType)
}

執行結果

https://ithelp.ithome.com.tw/upload/images/20230904/20115082lCpOnhuAGQ.jpg

Conclusion

在這篇文章中,我們演示了如何將生產筆電的過程分解成更小,更可管理的部分,同時我們也保有了下列的特點:

簡化性

我們通過將筆電類型設定的細節藏在各自的Builder(RogBuilder和AsusBuilder)之後,讓Director只需通過一個簡單的介面來創建筆電。

可擴展性

由於Builder是一個接口,往後可以輕鬆地添加更多類型的筆電,例如Dell或HP,而不需要更改Director。

單一責任

每個類別(Product, Builder, AsusBuilder, RogBuilder, Director)都只做一件事,符合單一責任原則。

可測試性

這種架構也有助於獨立測試各個組件,因為你可以簡單地替換或模擬Builder來測試Director的行為。

耦合度低

Director與筆電建造過程解耦,只需知道Builder介面即可。這意味著在未來需要變更或擴展時,你只需修改或添加新的Builder。


上一篇
Builder Pattern - 生成器模式
下一篇
Prototype Pattern - 原型模式
系列文
掘地土撥鼠的設計歷險記11
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言